package com.yunji.framework_template.books.web.controller;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.yunji.framework_template.biz.cache.CacheService;
import com.yunji.framework_template.books.biz.service.BooksChaptersService;
import com.yunji.framework_template.books.biz.service.BooksCrawlerService;
import com.yunji.framework_template.books.biz.service.BooksService;
import com.yunji.framework_template.books.orm.persistence.model.Books;
import com.yunji.framework_template.books.orm.persistence.model.BooksChapters;
import com.yunji.framework_template.common.util.ListUtil;
import com.yunji.framework_template.common.util.NumberUtil;
import com.yunji.framework_template.common.web.Page;
import com.yunji.framework_template.common.web.Result;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by fenglibin on 2019/01/16.
 */
@Slf4j
@Controller
@RequestMapping("/books/")
public class BooksController {

    @Resource
    private BooksService         booksService;
    @Resource
    private BooksCrawlerService  booksCrawlerService;
    @Resource
    private CacheService         cacheService;
    @Resource
    private BooksChaptersService booksChaptersService;

    @Value("#{settings['system.domain']}")
    private String               systemDomain;
    @Value("#{settings['http.protocol']}")
    private String               httpProtocol;
    @Value("#{settings['image.domain']}")
    private String               imageDomain;

    @RequestMapping("selectAll")
    @ResponseBody
    public Result<List<Books>> selectAll() {
        return Result.success(booksService.selectAll());
    }

    @RequestMapping("select")
    @ResponseBody
    public Result<Books> selectByPrimaryKey(Integer id) {
        return Result.success(booksService.selectByPrimaryKey(id));
    }

    @RequestMapping("selectByCondition")
    @ResponseBody
    public Result<List<Books>> selectByCondition(Books record) {
        return Result.success(booksService.selectByCondition(record));
    }

    @RequestMapping("count")
    @ResponseBody
    public Result<Integer> count(Books record) {
        return Result.success(booksService.count(record));
    }

    @RequestMapping("insert")
    @ResponseBody
    public Result<Integer> insertSelective(Books record) {
        return Result.success(booksService.insertSelective(record));
    }

    @RequestMapping("update")
    @ResponseBody
    public Result<Integer> updateByPrimaryKeySelective(Books record) {
        return Result.success(booksService.updateByPrimaryKeySelective(record));
    }

    @RequestMapping("selectByPage")
    @ResponseBody
    public Result<Page<List<Books>>> selectByPage(Page<Books> page) {
        List<Books> list = null;
        page = page.sequentialDisplayCalculate(booksService.count(page.getObj()));
        if (page.getTotalCount() > 0) {
            list = booksService.selectByPage(page);
        }
        Page<List<Books>> result = new Page<List<Books>>(page, list);
        return Result.success(result);
    }

    @RequestMapping("deleteByCondition1")
    @ResponseBody
    public Result<Integer> deleteByCondition(Books record) {
        return Result.success(booksService.deleteByCondition(record));
    }

    @RequestMapping("delete1")
    @ResponseBody
    public Result<Integer> deleteByPrimaryKey(Integer id) {
        return Result.success(booksService.deleteByPrimaryKey(id));
    }

    @RequestMapping("updateByPrimaryKeyWithBLOBs")
    @ResponseBody
    public Result<Integer> updateByPrimaryKeyWithBLOBs(Books record) {
        return Result.success(booksService.updateByPrimaryKeyWithBLOBs(record));
    }

    @RequestMapping(value = "/crawleBooks", method = { RequestMethod.GET })
    @ResponseBody
    public String crawleBooks(HttpServletRequest request, HttpServletResponse response) throws IOException {
        new Thread() {

            public void run() {
                try {
                    booksCrawlerService.crawleBooks();
                } catch (Exception e) {
                    log.error("Crawle books exception happened:" + e.getMessage(), e);
                }
            }
        }.start();
        return "OK";
    }

    @RequestMapping(value = "/initBooks", method = { RequestMethod.GET })
    @ResponseBody
    public String initBooks(HttpServletRequest request, HttpServletResponse response) throws IOException {
        cacheService.initBooks();
        return "OK";
    }

    /**
     * Home page
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws HttpException,
                                                                                        IOException {
        log.info("Book index is accessed.");
        ModelAndView view = new ModelAndView("book/book_index");
        view.getModelMap().addAttribute("indexType", "Book");
        view.getModelMap().addAttribute("systemDomain", systemDomain);
        view.getModelMap().addAttribute("imageDomain", imageDomain);
        List<Books> bookList = booksService.getBookByPageIndex(1);
        if (bookList != null) {
            bookList = ListUtil.randomSort(bookList);
        }
        view.getModelMap().addAttribute("booksList", bookList);
        return view;
    }

    /**
     * Detail page
     */
    @RequestMapping(value = "/detail/{bookId}", method = RequestMethod.GET)
    public ModelAndView detail(@PathVariable("bookId") String bookId) throws HttpException, IOException {
        log.info("Detail access bookId is:" + bookId);
        if (!NumberUtil.isNumber(bookId)) {
            log.warn("The bookId is not number:" + bookId);
            return new ModelAndView("404");
        }
        int nid = Integer.parseInt(bookId);
        Books book = booksService.selectByPrimaryKey(nid);
        if (book == null) {
            log.warn("Cannot get book by bookId:" + bookId);
            return new ModelAndView("404");
        }

        ModelAndView view = new ModelAndView("book/book_detail");
        view.getModelMap().addAttribute("systemDomain", systemDomain);
        view.getModelMap().addAttribute("httpProtocol", httpProtocol);
        view.getModelMap().addAttribute("imageDomain", imageDomain);
        // 当前电子书
        view.getModelMap().put("book", book);
        // 所有的章节
        List<BooksChapters> bookChapterList = book.getBooksChaptersList();
        if (bookChapterList == null) {
            bookChapterList = booksChaptersService.selectByBookId(book.getId());
            if (bookChapterList != null) {
                book.setBooksChaptersList(bookChapterList);
                book.setFirstChapter(booksChaptersService.selectByPrimaryKey(bookChapterList.get(0).getId()));
            }
        }
        view.getModelMap().put("bookChapterList", bookChapterList);
        // 推荐的电子书
        view.getModelMap().put("bookRecommendList", booksService.getRandomBooks());
        // 增加查看次数
        booksService.updateReadTimesByPrimaryKey(book);
        book.setReadTimes(book.getReadTimes() + 1);
        cacheService.getCountryCache().getBooks().put(book.getId(), book);
        return view;
    }

    /**
     * Detail page
     */
    @RequestMapping(value = "/chapter/{bookId}/{chapterIndexId}", method = RequestMethod.GET)
    public ModelAndView chapter(@PathVariable("bookId") String bookId,
                                @PathVariable("chapterIndexId") String chapterIndexId) throws HttpException,
                                                                                       IOException {
        log.info("Detail access bookId is:" + bookId);
        if (!NumberUtil.isNumber(bookId)) {
            log.warn("The bookId is not number:" + bookId);
            return new ModelAndView("404");
        }
        int bid = Integer.parseInt(bookId);
        Books book = booksService.selectByPrimaryKey(bid);
        if (book == null) {
            log.warn("Cannot get book by bookId:" + bookId);
            return new ModelAndView("404");
        }

        log.info("Chapter access chapterIndexId is:" + chapterIndexId);
        if (!NumberUtil.isNumber(chapterIndexId)) {
            log.warn("The chapterIndexId is not number:" + chapterIndexId);
            return new ModelAndView("404");
        }
        int cid = Integer.parseInt(chapterIndexId);
        BooksChapters booksChapters = booksChaptersService.selectByBookIdAndChapterIndex(bid, cid);
        if (booksChapters == null) {
            log.warn("Cannot get book by bookId:" + bid + ", chapterIndexId:" + chapterIndexId);
            return new ModelAndView("404");
        }
        ModelAndView view = new ModelAndView("book/book_chapter");
        view.getModelMap().addAttribute("systemDomain", systemDomain);
        view.getModelMap().addAttribute("httpProtocol", httpProtocol);
        view.getModelMap().addAttribute("imageDomain", imageDomain);
        booksChaptersService.updateReadTimesByPrimaryKey(booksChapters);
        view.getModelMap().put("book", book);
        view.getModelMap().put("chapter", booksChapters);
        view.getModelMap().put("preChapterIndexId", (cid > 1) ? String.valueOf(cid - 1) : "");
        view.getModelMap().put("nextChapterIndexId", (cid < book.getChapters()) ? String.valueOf(cid + 1) : "");
        return view;
    }
}
